﻿#ifndef GLOBAL_H
#define GLOBAL_H

#include "Qss.h"
#include <QWidget>
#include <QDebug>
#include <QMutex>
#include <QDateTime>

extern "C"{
    #include "libmodbus/modbus.h"
}


#if defined(_MSC_VER) && (_MSC_VER >= 1600)
# pragma execution_character_set("utf-8")
#endif



typedef struct {
  int addr;
  uint16_t *val1;
  uint16_t len;
  QString time;
  bool succ;
}CapData;


typedef struct{
  uint16_t addr;
  uint16_t len;

}Req;

typedef struct T_Config{
    QString com;
    int baurate;
    int addr;
    int rate;
    QList<Req> req;
}Config;


class ASyncReadData :public QSSASyncProcess{
public:
    ASyncReadData(QWidget *parent)
        :QSSASyncProcess(parent){

    }
    ~ASyncReadData(){
        if(mMod)
          modbus_close(mMod);
    }
    void Stop(){
        mRuning = false;
    }
    void AddMonitor(QString addr){

    }
    void AddConfig(Config *c){
        if(nullptr != c){
          mMux.lock();
          for(auto itr = mConf.begin();itr != mConf.end();
              itr++){
              if (c == *itr){
                mMux.unlock();
                return;
              }
          }
          this->mConf.append(c);
          mMux.unlock();
        }
    }
    void Pause(){
      mPause = true;
    }
    void Continue(){
      mPause = false;
    }
    void Run(void *v) override{
        // 读取1
        float x = 0;
        while(mRuning){
            int count = 0;
            if(mPause){
                QThread::msleep(100);
                continue;
              }

            for(int it = 0;it < mConf.size();it++) {
                auto itr = mConf.at(it);
                uint16_t dat[10] = {0};

                if(mMod == nullptr){
                    mMod = modbus_new_rtu(itr->com.toStdString().c_str(),
                                          itr->baurate, 'N', 8, 1);   //相同的端口只能同时打开一个

                    modbus_set_debug(mMod,true);
                    modbus_set_slave(mMod,itr->addr);  //设置modbus从机地址
                    modbus_connect(mMod);
                    modbus_set_response_timeout(mMod,3,0);
                  }



                for(auto s = 0;s < itr->req.length();s++){
                    QThread::msleep(itr->rate);
                    int ret = modbus_read_registers(mMod,itr->req[s].addr,itr->req[s].len,dat);

                    mMux.lock();
                    QString log = QDateTime::currentDateTime().toString("yyyy-mm-dd hh:MM:ss ") +  "发送数据:";
                    for(int i =0;i < req_length;i++){
                        log += QString::asprintf("0x%02x ",req[i]);
                      }
                    emit(Info(log));


                    log = QDateTime::currentDateTime().toString("yyyy-mm-dd hh:MM:ss ") + "接收数据:";

                    for(int i =0;i < resp_length;i++){
                        log += QString::asprintf("0x%02x ",rsp[i]);
                      }
                    if(ret < 0){
                        log += "超时";
                      }
                    emit(Info(log));
                    bool succ = true;

                    if(mListData.contains(itr->addr)){
                        if(ret < 0){
                            succ = false;
                        }
                        uint16_t *val = new uint16_t[itr->req[s].len];

                        memcpy(val,dat,itr->req[s].len*2);
                        mListData[itr->addr]->push_front(new CapData{
                                                           itr->req[s].addr,
                                                           val,
                                                           itr->req[s].len,
                                                           QDateTime::currentDateTime().toString("yyyy-mm-dd hh:MM:ss"),
                                                           true
                                                         });
                      }else{
                        uint16_t *val = new uint16_t[itr->req[s].len];

                        mListData[itr->addr] = new QList<CapData *>;
                        mListData[itr->addr]->push_front(new CapData{
                                                           itr->req[s].addr,
                                                           val,
                                                           itr->req[s].len,
                                                           QDateTime::currentDateTime().toString("yyyy-mm-dd hh:MM:ss"),
                                                           succ
                                                         });
                      }
                    mMux.unlock();
                  }
              }
            qDebug()<<"keep alive";
            QThread::msleep(100);

          }
        modbus_close(mMod);

        // 读取2
    }

    int TakeLast(int addr,CapData **p){
        if(this->mListData.contains(addr)){
            mMux.lock();
            if(mListData[addr]->size() > 0){
                *p = (CapData *)mListData[addr]->takeLast();
                mMux.unlock();
                return 0;
            }else{
                mMux.unlock();
                return -1;
            }
        }else{
            return -1;
        }
    }
    QMap<int,QList<CapData *>*> mListData;
    QMutex mMux;
    modbus_t* mMod = nullptr;
    bool mRuning;
    QList<Config*> mConf;
    bool mPause = false;
};

extern ASyncReadData *gAsyncData;



#endif // GLOBAL_H
